<?php
$host = '0.0.0.0';
$port = 8071;
$fd = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
socket_set_option($fd, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind( $fd, $host, $port );
socket_listen( $fd );

socket_set_nonblock( $fd );

$event_arr = [];
$conn_arr = [];

echo PHP_EOL.PHP_EOL."欢迎来到ti-chat聊天室!发言注意遵守当地法律法规!".PHP_EOL;
echo "        tcp://{$host}:{$port}".PHP_EOL;

$event_base = new EventBase();

$event = new Event( $event_base, $fd, Event::READ | Event::PERSIST, function( $fd )
{
    // 使用全局的event_arr 和 conn_arr
    global $event_arr,$conn_arr,$event_base;
    // 非阻塞模式下，注意accpet的写法会稍微特殊一些。如果不想这么写，请往前面添加@符号，不过不建议这种写法
    if( ( $conn = socket_accept( $fd ) ) != false ){
        echo date('Y-m-d H:i:s').'：欢迎'.intval( $conn ).'来到聊天室'.PHP_EOL;
        socket_set_nonblock( $conn );
        $conn_arr[ intval( $conn ) ] = $conn;
        $event = new Event( $event_base, $conn, Event::READ | Event::PERSIST, function( $conn )
        {
            global $conn_arr;
            global $event_arr;
            $buffer = trim(socket_read( $conn, 65535 ));
            $msg = intval( $conn ).' say : '.$buffer.PHP_EOL;
            if($buffer=='quit'){
                unset($conn_arr[intval($conn)]);
                unset($event_arr[intval($conn)]);
                socket_close($conn);
                $buffer="Good bye!";
                $msg = intval( $conn ).' say : '.$buffer.PHP_EOL;
            }

            echo $msg.PHP_EOL;
            //向其它连接的用户发消息
            foreach( $conn_arr as $conn_key => $conn_item ){
                if( $conn != $conn_item ){
                    socket_write( $conn_item, $msg, strlen( $msg ) );
                }
            }

        }, $conn );

        $event->add();
        $event_arr[ intval( $conn ) ] = $event;
    }
}, $fd );

$event->add();
$event_base->loop();